﻿using DevExpress.Data.Filtering;
using DevExpress.Data.Filtering.Helpers;
using Volo.Abp.DependencyInjection;
using YAPACS.BusinessObjects.Exams;
using YAPACS.Workflows;

namespace YAPACS.RisServer.Workflows.Report
{
    public class AdvancedSearchExpression : WorkflowBase, IAdvancedSearchExpression, ITransientDependency
    {
        protected override async Task<WorkflowOutput> InvokeCoreAsync(WorkflowInput input)
        {
            string condition = " where 1=1 ";
            const string key = "Input";
            CriteriaOperator criteriaOperator = null;
            if (input.ContainsKey(key) && input.GetValueOrDefault(key) is Dictionary<string, object> search)
            {
                //默认查询条件
                //检查号，姓名，设备类型（选择）,设备（选择），登记时间段
                //返回CriteriaOperator
                if (!search.ContainsKey("examTimeRange"))
                {
                    search.Add("examTimeRange", string.Join(",", [DateTime.Today.ToString("yyyy-MM-dd"), DateTime.Today.ToString("yyyy-MM-dd")]));
                }
                foreach (var item in search)
                {
                    //检查号
                    if (item.Key.EqualsIgnoreCase("AccessionNumber"))
                    {
                        var value = item.Value as string;
                        if (!string.IsNullOrWhiteSpace(value))
                        {
                            var criteria = CriteriaOperator.FromLambda<Exam>(e => e.AccessionNumber == value);
                            criteriaOperator = CriteriaOperator.And(criteriaOperator, criteria);
                            condition += " and AccessionNumber=@AccessionNumber";
                        }
                    }
                    //患者姓名
                    if (item.Key.EqualsIgnoreCase("Name"))
                    {
                        var value = item.Value as string;
                        if (!string.IsNullOrWhiteSpace(value))
                        {
                            criteriaOperator = CriteriaOperator.And(criteriaOperator, CriteriaOperator.FromLambda<Exam>(e => e.Patient != null));
                            if (value.Contains('*'))
                            {
                                var array = value.Split('*');
                                foreach (var arr in array)
                                {
                                    if (!string.IsNullOrWhiteSpace(arr))
                                    {
                                        var criteria = CriteriaOperator.FromLambda<Exam>(e => e.Patient.Name.Contains(arr));
                                        criteriaOperator = CriteriaOperator.And(criteriaOperator, criteria);
                                    }
                                }
                            }
                            else
                            {
                                var criteria = CriteriaOperator.FromLambda<Exam>(e => e.Patient.Name == value);
                                criteriaOperator = CriteriaOperator.And(criteriaOperator, criteria);
                                condition += " and PatientName=@Name";
                            }
                        }
                    }
                    //性别
                    if (item.Key.EqualsIgnoreCase("PatientSex"))
                    {
                        if (int.TryParse(item.Value?.ToString(), out int sex))
                        {
                            var value = (PatientSex)sex;
                            var criteria = CriteriaOperator.FromLambda<Exam>(e => e.Patient != null && e.Patient.Sex == value);
                            criteriaOperator = CriteriaOperator.And(criteriaOperator, criteria);
                            condition += $" and Sex='{(value == PatientSex.Female ? "女" : value == PatientSex.Male ? "男" : "不详")}'";
                        }
                    }
                    //患者Id
                    if (item.Key.EqualsIgnoreCase("PatientId"))
                    {
                        var value = item.Value as string;
                        if (!string.IsNullOrWhiteSpace(value))
                        {
                            var criteria = CriteriaOperator.FromLambda<Exam>(e => e.Patient != null && e.Patient.PatientId == value);
                            criteriaOperator = CriteriaOperator.And(criteriaOperator, criteria);
                            condition += " and PatientId=@PatientId";
                        }
                    }
                    //呼叫编号
                    if (item.Key.EqualsIgnoreCase("CallNumber"))
                    {
                        var value = item.Value as string;
                        if (!string.IsNullOrWhiteSpace(value))
                        {
                            var criteria = CriteriaOperator.FromLambda<Exam>(e => e.ExamQueuing != null && e.ExamQueuing.CallNumber == value);
                            criteriaOperator = CriteriaOperator.And(criteriaOperator, criteria);
                        }
                    }
                    //预约编号
                    if (item.Key.EqualsIgnoreCase("AppointmentNumber"))
                    {
                        var value = item.Value as string;
                        if (!string.IsNullOrWhiteSpace(value))
                        {
                            var criteria = CriteriaOperator.FromLambda<Exam>(e => e.ExamAppointment != null && e.ExamAppointment.AppointmentNumber == value);
                            criteriaOperator = CriteriaOperator.And(criteriaOperator, criteria);
                        }
                    }
                    //门诊号
                    if (item.Key.EqualsIgnoreCase("OutPatientNumber"))
                    {
                        var value = item.Value as string;
                        if (!string.IsNullOrWhiteSpace(value))
                        {
                            var criteria = CriteriaOperator.FromLambda<Exam>(e => e.OutPatientNumber == value);
                            criteriaOperator = CriteriaOperator.And(criteriaOperator, criteria);
                            condition += " and OutPatientNumber=@OutPatientNumber";
                        }
                    }
                    //住院号
                    if (item.Key.EqualsIgnoreCase("InPatientNumber"))
                    {
                        var value = item.Value as string;
                        if (!string.IsNullOrWhiteSpace(value))
                        {
                            var criteria = CriteriaOperator.FromLambda<Exam>(e => e.InPatientNumber == value);
                            criteriaOperator = CriteriaOperator.And(criteriaOperator, criteria);
                            condition += " and InPatientNumber=@InPatientNumber";
                        }
                    }
                    //体检号
                    if (item.Key.EqualsIgnoreCase("PhysicalExamNumber"))
                    {
                        var value = item.Value as string;
                        if (!string.IsNullOrWhiteSpace(value))
                        {
                            var criteria = CriteriaOperator.FromLambda<Exam>(e => e.PhysicalExamNumber == value);
                            criteriaOperator = CriteriaOperator.And(criteriaOperator, criteria);
                            condition += " and PhysicalExamNumber=@PhysicalExamNumber";
                        }
                    }
                    //检查时间（范围）//创建时间
                    string examTimeRange = default;
                    if (item.Key.EqualsIgnoreCase("ExamTimeRange"))
                    {
                        examTimeRange = item.Value as string;
                        if (string.IsNullOrWhiteSpace(examTimeRange))
                        {
                            examTimeRange = string.Join(",", [DateTime.Today.ToString("yyyy-MM-dd"), DateTime.Today.ToString("yyyy-MM-dd")]);
                        }
                        var timeRange = examTimeRange.Split(',');
                        var startTime = DateTime.Parse(timeRange[0]).Date;
                        var endTime = DateTime.Parse(timeRange[1]).AddDays(1).Date;
                        criteriaOperator = CriteriaOperator.And(criteriaOperator, CriteriaOperator.FromLambda<Exam>(e =>(e.ExamQueuing!=null&&e.ExamQueuing.QueuingTime>=startTime&&e.ExamQueuing.QueuingTime<endTime) || (e.ExamTime != null && e.ExamTime >= startTime && e.ExamTime < endTime)||(e.ExamQueuing==null&&e.ExamTime==null && e.RegisterTime >= startTime && e.RegisterTime < endTime)));
                        condition += " and ((ExamTime>=@StartTime and ExamTime< @EndTime) or (RegisterTime>=@StartTime and RegisterTime< @EndTime))";
                    }
                    //联系方式（联系方式1和联系方式2）
                    if (item.Key.EqualsIgnoreCase("PhoneNumber"))
                    {
                        var value = item.Value as string;
                        if (!string.IsNullOrWhiteSpace(value))
                        {
                            var criteria = CriteriaOperator.FromLambda<Exam>(e => e.Patient != null && (e.Patient.PhoneNumber == value || e.Patient.PhoneNumber2 == value));
                            criteriaOperator = CriteriaOperator.And(criteriaOperator, criteria);
                            condition += " and PhoneNumber=@PhoneNumber";
                        }
                    }
                    //证件号码
                    if (item.Key.EqualsIgnoreCase("IdCardNumber"))
                    {
                        var value = item.Value as string;
                        if (!string.IsNullOrWhiteSpace(value))
                        {
                            var criteria = CriteriaOperator.FromLambda<Exam>(e => e.Patient != null && e.Patient.IdCardNumber == value);
                            criteriaOperator = CriteriaOperator.And(criteriaOperator, criteria);
                            condition += " and IdCardNumber=@IdCardNumber";
                        }
                    }
                    //检查项目（多选）
                    if (item.Key.EqualsIgnoreCase("ExamItems"))
                    {
                        var value = item.Value as string;
                        if (!string.IsNullOrWhiteSpace(value))
                        {
                            var examItems = value.Split(',').Select(Guid.Parse).Take(10);
                            foreach (var examItem in examItems)
                            {
                                var criteria = CriteriaOperator.FromLambda<Exam>(e => e.ExamItems.Any(g => g.Oid == examItem));
                                criteriaOperator = CriteriaOperator.And(criteriaOperator, criteria);
                                condition += $" and charindex('{examItem}',ExamItems)>0 ";
                            }
                        }
                    }
                    //申请科室（多选）
                    if (item.Key.EqualsIgnoreCase("ApplyDepartments"))
                    {
                        var value = item.Value as string;
                        if (!string.IsNullOrWhiteSpace(value))
                        {
                            var applyDepartments = value.Split(',').Select(Guid.Parse).Take(10);
                            var criteria = CriteriaOperator.FromLambda<Exam>(e => e.ApplyDepartment != null && applyDepartments.Contains(e.ApplyDepartment.Oid));
                            criteriaOperator = CriteriaOperator.And(criteriaOperator, criteria);
                            condition += $" and charindex(ApplyDepartment,@ApplyDepartments)>0 ";
                        }
                    }
                    //检查部位（多选）
                    if (item.Key.EqualsIgnoreCase("ExamBodyParties"))
                    {
                        var value = item.Value as string;
                        if (!string.IsNullOrWhiteSpace(value))
                        {
                            var examBodyParties = value.Split(',').Select(Guid.Parse).Take(10);
                            foreach (var examBodyParty in examBodyParties)
                            {
                                var criteria = CriteriaOperator.FromLambda<Exam>(e => e.ExamBodyParties.Any(g => g.Oid == examBodyParty));
                                criteriaOperator = CriteriaOperator.And(criteriaOperator, criteria);
                                condition += $" and charindex('{examBodyParty}',ExamBodyParties)>0 ";
                            }
                        }
                    }
                    //检查结果（单选）
                    if (item.Key.EqualsIgnoreCase("ExamResult"))
                    {
                        var value = (ExamResult)(Convert.ToInt32(item.Value));
                        var criteria = CriteriaOperator.FromLambda<Exam>(e => e.Report != null && e.Report.ExamResult == value);
                        criteriaOperator = CriteriaOperator.And(criteriaOperator, criteria);
                        condition += $" and ExamResult='{(value == ExamResult.Negative ? "阴性" : value == ExamResult.Positive ? "阳性" : "不详")}'";
                    }
                    //检查设备（多选）
                    if (item.Key.EqualsIgnoreCase("ExamDevices"))
                    {
                        var value = item.Value as string;
                        if (!string.IsNullOrWhiteSpace(value))
                        {
                            var examDevices = value.Split(',').Select(Guid.Parse).Take(10);
                            var criteria = CriteriaOperator.FromLambda<Exam>(e => e.ExamDevice != null && examDevices.Contains(e.ExamDevice.Oid));
                            criteriaOperator = CriteriaOperator.And(criteriaOperator, criteria);
                            condition += $" and charindex(ExamDevice,@ExamDevices)>0 ";
                        }
                    }
                    //检查类别（多选）
                    if (item.Key.EqualsIgnoreCase("ExamCategories"))
                    {
                        var value = item.Value as string;
                        if (!string.IsNullOrWhiteSpace(value))
                        {
                            var examCategories = value.Split(',').Select(Guid.Parse).Take(10);
                            var criteria = CriteriaOperator.FromLambda<Exam>(e => e.ExamCategory != null && examCategories.Contains(e.ExamCategory.Oid));
                            criteriaOperator = CriteriaOperator.And(criteriaOperator, criteria);
                            condition += $" and charindex(ExamCategory,@ExamCategories)>0 ";
                        }
                    }
                    //设备类型（多选）
                    if (item.Key.EqualsIgnoreCase("DeviceTypes"))
                    {
                        var value = item.Value as string;
                        if (!(string.IsNullOrWhiteSpace(value) || value == "全部"))
                        {
                            var deviceTypes = value.Split(',').Take(10);
                            var criteria = CriteriaOperator.FromLambda<Exam>(e => e.DeviceType != null && deviceTypes.Contains(e.DeviceType.Code));
                            criteriaOperator = CriteriaOperator.And(criteriaOperator, criteria);
                            condition += $" and charindex(DeviceType,@DeviceTypes)>0 ";
                        }
                    }
                    //医疗机构
                    if (item.Key.EqualsIgnoreCase("Institution"))
                    {
                        var value = item.Value as string;
                        if (!string.IsNullOrWhiteSpace(value))
                        {
                            var institutions = value.Split(',');
                            var criteria = CriteriaOperator.FromLambda<Exam>(e => e.Department != null && e.Department.Institution != null && institutions.Contains(e.Department.Institution.Code));
                            criteriaOperator = CriteriaOperator.And(criteriaOperator, criteria);
                        }
                    }
                    //报告状态
                    if (item.Key.EqualsIgnoreCase("ExamStatus"))
                    {
                        var value = item.Value as string;
                        if (!(string.IsNullOrWhiteSpace(value) || value == "全部"))
                        {
                            var examStatusArr = value.Split(',');
                            CriteriaOperator statuscriteriaOperator = null;
                            if (examStatusArr.Contains("未报告"))
                            {
                                var criteria = CriteriaOperator.FromLambda<Exam>(e => e.Report == null && e.ExamStatus == ExamStatus.Report);
                                statuscriteriaOperator = CriteriaOperator.Or(statuscriteriaOperator, criteria);
                            }
                            if (examStatusArr.Contains("报告中"))
                            {
                                var criteria = CriteriaOperator.FromLambda<Exam>(e => e.Report != null && e.Report.ReportStatus == ReportStatus.Reporting);
                                statuscriteriaOperator = CriteriaOperator.Or(statuscriteriaOperator, criteria);
                            }
                            if (examStatusArr.Contains("未审核"))
                            {
                                var criteria = CriteriaOperator.FromLambda<Exam>(e => e.Report != null && e.Report.ReportStatus == ReportStatus.Reported || e.Report.ReportStatus == ReportStatus.Audited);
                                statuscriteriaOperator = CriteriaOperator.Or(statuscriteriaOperator, criteria);
                            }
                            if (examStatusArr.Contains("审核中"))
                            {
                                var criteria = CriteriaOperator.FromLambda<Exam>(e => e.Report != null && e.Report.ReportStatus == ReportStatus.Auditing || e.Report.ReportStatus == ReportStatus.Reviewing);
                                statuscriteriaOperator = CriteriaOperator.Or(statuscriteriaOperator, criteria);
                            }
                            if (examStatusArr.Contains("已完成"))
                            {
                                var criteria = CriteriaOperator.FromLambda<Exam>(e => e.Report != null && e.Report.ReportStatus == ReportStatus.Completed);
                                statuscriteriaOperator = CriteriaOperator.Or(statuscriteriaOperator, criteria);
                            }
                            if (examStatusArr.Contains("未打印"))
                            {
                                var criteria = CriteriaOperator.FromLambda<Exam>(e => new ExamStatus[] { ExamStatus.Report, ExamStatus.Completed }.Contains(e.ExamStatus) && e.Report != null && e.Report.PrintingTimes == 0);
                                statuscriteriaOperator = CriteriaOperator.Or(statuscriteriaOperator, criteria);
                            }
                            if (examStatusArr.Contains("已打印"))
                            {
                                var criteria = CriteriaOperator.FromLambda<Exam>(e => new ExamStatus[] { ExamStatus.Report, ExamStatus.Completed }.Contains(e.ExamStatus) && e.Report != null && e.Report.PrintingTimes > 0);
                                statuscriteriaOperator = CriteriaOperator.Or(statuscriteriaOperator, criteria);
                            }
                            criteriaOperator = CriteriaOperator.And(criteriaOperator, statuscriteriaOperator);
                        }
                    }
                }
            }
            if (criteriaOperator.ReferenceEqualsNull())
            {
                criteriaOperator = CriteriaOperator.FromLambda<Exam>(e => false);
            }
            input.Add("Output", criteriaOperator);
            input.Add("ArchiveOutput", condition);
            return await Task.FromResult(new WorkflowOutput
            {
                Success = true
            });
        }
    }
}
